1、题干
给你一个由若干 0 和 1 组成的二维网格 grid,请你找出边界全部由 1 组成的最大 正方形 子网格,并返回该子网格中的元素数量。如果不存在,则返回 0。
示例 1:
输入:grid = [[1,1,1],[1,0,1],[1,1,1]]
输出:9
示例 2:
输入:grid = [[1,1,0,0]]
输出:1
提示:
1 <= grid.length <= 1001 <= grid[0].length <= 100grid[i][j]为0或1
2、思路
纯模拟,毫无技巧,全是感情🤡
遍历网格,以当前网格单元作为正方形左上顶点,先求出左上两条边长的最大可能值,再验证右下两条边是否满足要求。
优化代码又折腾了一番,速度得到一些提升,从最快 88ms 达到最快 68ms。
主要优化在于检查边长的时候,由于是正方形可以同时检查两条边。做法是固定起始位置,然后改变边长,两条边同时满足要求时才往下遍历。
3、代码
function largest1BorderedSquare(grid: number[][]): number {
    let maxLen = 0;
    const m = grid.length, n = grid[0].length;
    for (let i = 0; i < m - maxLen; i++) {
        for (let j = 0; j < n - maxLen; j++) {
            if (!grid[i][j]) continue;
            let len = 1;
            while (grid[i][j + len] && grid[i + len]?.at(j)) len++;
            for (; len > maxLen; len--) {
                let step = 1, ei = i + len - 1, ej = j + len - 1;
                while (step < len && grid[i + step][ej] && grid[ei][j + step]) step++;
                if (step === len) maxLen = len;
            }
        }
    }
    return maxLen ** 2;
};
下面是最开始的代码,可以对照看看
function largest1BorderedSquare(grid: number[][]): number {
    let maxLen = 0;
    const m = grid.length, n = grid[0].length;
    for (let i = 0; i < m - maxLen; i++) {
        for (let j = 0; j < n - maxLen; j++) {
            if (!grid[i][j]) continue;
            let si = i + 1, sj = j + 1;
            while (si < m && grid[si]?.at(j)) si++;
            while (sj < n && grid[i][sj]) sj++;
            let len = Math.min(si - i, sj - j);
            for (; len > maxLen; len--) {
                let ei = i + len - 1, ej = j + len - 1;
                while (ei > i && grid[ei][j + len - 1]) ei--;
                while (ej > j && grid[i + len - 1][ej]) ej--;
                if (ei === i && ej === j) maxLen = Math.max(maxLen, len);
            }
        }
    }
    return maxLen ** 2;
};
4、复杂度
- 时间复杂度:最差
 - 空间复杂度:
 
5、执行结果
